package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vo.HotApArticleVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import com.heima.apis.wemedia.IWemediaClient;

import java.util.*;
import java.util.stream.Collectors;

import static com.heima.common.constants.ArticleConstants.*;

public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper articleMapper;

    /**
     * 计算热点文章业务方法
     */
    @Override
    public void computeHotArticle() {
        //1.计算前五天的文章列表
        List<ApArticle> articleList = last5DayArticleList();

        //2.计算文章分值
        List<HotApArticleVo> ArticleScoreVoList = sumArticleScore(articleList);

        //3.计算分值之后，30条分值较高的存入redis,
        toRedis(ArticleScoreVoList);

    }

    @Autowired
    private IWemediaClient wemediaClient;

    @Autowired
    private StringRedisTemplate redisTemplate;

    //抽取3.计算分值之后，30条分值较高的存入redis,
    private void toRedis(List<HotApArticleVo> articleScoreVoList) {
        ResponseResult channels = wemediaClient.getChannels();
        if (channels.getCode() == 200) {
            String jsonString = JSON.toJSONString(channels.getData());
            List<WmChannel> wmChannels = JSON.parseArray(jsonString, WmChannel.class);
            if (wmChannels != null || wmChannels.size() > 0) {
                for (WmChannel wmChannel : wmChannels) {
                    List<HotApArticleVo> voList = articleScoreVoList.stream().filter(x ->
                            x.getChannelId().equals(wmChannel.getId())
                    ).sorted(Comparator.comparing(HotApArticleVo::getScore).reversed()
                    ).limit(30).collect(Collectors.toList());
                    String key = "HOT_ARTICLE_" + wmChannel.getId();
                    redisTemplate.opsForValue().set(key, JSON.toJSONString(voList));
                }
            }
        }
        List<HotApArticleVo> voList1 = articleScoreVoList.stream()
                .sorted(Comparator.comparing(HotApArticleVo::getScore).reversed()
                ).limit(30).collect(Collectors.toList());
        String key = "HOT_ARTICLE" + DEFAULT_TAG;
        redisTemplate.opsForValue().set(key, JSON.toJSONString(voList1));
    }

    //抽取方法2.计算文章分值
    private List<HotApArticleVo> sumArticleScore(List<ApArticle> articleList) {

        List<HotApArticleVo> articleScoreList = new ArrayList<>();

        //1.判断非空
        if (articleList == null || articleList.size() <= 0) {
            return null;
        }
        //2.计算分值
        for (ApArticle apArticle : articleList) {
            HotApArticleVo vo = new HotApArticleVo();
            BeanUtils.copyProperties(apArticle, vo);
            //计算分数
            Integer score = hotArticleScore(apArticle);
            vo.setScore(score);
            articleScoreList.add(vo);
        }
        return articleScoreList;
    }

    //抽取计算分数
    private Integer hotArticleScore(ApArticle apArticle) {
        Integer score = 0;
        if (apArticle.getLikes() != null) {
            score += apArticle.getLikes() * HOT_ARTICLE_LIKE_WEIGHT;
        }
        if (apArticle.getViews() != null) {
            score += apArticle.getViews();
        }
        if (apArticle.getComment() != null) {
            score += apArticle.getComment() * HOT_ARTICLE_COMMENT_WEIGHT;
        }
        if (apArticle.getCollection() != null) {
            score += apArticle.getCollection() * HOT_ARTICLE_COLLECTION_WEIGHT;
        }
        return score;
    }

    //抽取方法1.计算前五天的文章列表
    private List<ApArticle> last5DayArticleList() {
        //2.获取前五天的日期
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -5);
        Date before5Day = calendar.getTime();

        //调用接口
        List<ApArticle> listByLast5days = articleMapper.findArticleListByLast5days(before5Day);
        return listByLast5days;
    }
}
